<template>
  <div>
    <el-upload
      :action="`${api}/admin/uploads`"
      :class="{ hide: fileList.length >= limit }"
      :data="data"
      :drag="true"
      :file-list="fileList"
      :headers="headers"
      :limit="limit"
      :multiple="true"
      :on-exceed="limitAlert"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :on-success="uploadSuccess"
      list-type="picture-card"
      v-bind="$attrs"
    >
      <i class="el-icon-plus" />
    </el-upload>
    <el-dialog
      :append-to-body="true"
      :visible.sync="dialogVisible"
    >
      <img :src="dialogImageUrl" alt="" width="100%">
    </el-dialog>
  </div>
</template>

<script>
import { getToken } from '@/utils/auth'

export default {
  name: 'UploadImage',
  model: {
    prop: 'value',
    event: 'update'
  },
  props: {
    data: {
      type: Object,
      default: () => {
        return {}
      }
    },
    value: {
      type: [Array, String],
      default: () => []
    },
    limit: {
      type: Number,
      default: 100
    },
    api: {
      type: String,
      default: window.global.baseURL
    },
    isHost: { // 是否需要域名
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      init: true,
      dialogVisible: false,
      dialogImageUrl: '', // 预览图片
      fileList: [],
      renderFileList: [],
      allPicList: [],
      headers: {
        'Authorization': getToken()
      }
    }
  },
  watch: {
    value: {
      // 由于传递进来的值是不带域名的，所以需要格式化一下
      handler(val) {
        if (!val) return
        if (val instanceof Array) {
          this.fileList = val.map(item => {
            return {
              name: typeof item === 'object' ? item.name : item,
              url: this.formatImgUrl(typeof item === 'object' ? item.name : item)
            }
          })
        } else {
          this.fileList = [{
            name: val,
            url: this.formatImgUrl(val)
          }]
        }
      },
      immediate: true
    }
  },
  created() {

  },
  methods: {
    // 初始化域名
    formatImgUrl(url) {
      if (!url) return
      if (String(url).indexOf('http') > -1) {
        return url
      } else {
        // url开头不是/，则加上/
        if (String(url).indexOf('/') !== 0) {
          url = '/' + url
        }
        return this.api + url
      }
    },
    // 上传数量限制
    limitAlert() {
      this.$message({
        message: '最多只能上传' + this.limit + '张图片',
        type: 'warning'
      })
    },
    // 预览
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    judgeUrlValue(item) {
      return item.response ? item.response.data.url : item.url
    },
    removeHost(url) {
      // isHost 默认需要域名所以不清除
      return this.isHost ? url : url.replace(this.api, '')
    },
    // 上传成功
    uploadSuccess(res, file, fileList) {
      console.log('🚀 图片上传成功：', res, file, fileList)
      this.allPicList = fileList.map(item => {
        return {
          name: item.name,
          url: this.judgeUrlValue(item)
        }
      })
      const result = fileList.map(item => {
        return this.removeHost(this.judgeUrlValue(item))
      })
      this.$emit('update', result)
    },
    // 删除操作
    handleRemove(file, fileList) {
      this.allPicList = fileList.map(item => {
        return {
          name: item.name,
          url: this.judgeUrlValue(item)
        }
      })
      this.$emit('update', fileList.map(item => {
        return this.removeHost(this.judgeUrlValue(item))
      }))
    }
  }
}
</script>

<style lang="scss">
.el-upload--picture-card {
  background-color: #fbfdff;
  border: 1px dashed #c0ccda;
  border-radius: 6px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  width: 148px;
  height: 148px;
  cursor: pointer;
  line-height: 146px;
  vertical-align: top;
}

.el-upload-dragger {
  width: 148px;
  height: 148px;
  margin: -1px;
}

.el-upload-list--picture-card .el-upload-list__item {
  width: 148px;
  height: 148px;

  transition: none !important;
}

.hide {
  .el-upload--picture-card {
    display: none !important;
  }
}
</style>
